/*
* 串口1 与上位机通讯
* 串口2 DBUS DMA接收遥控器数据
* 串口3 485总线
* 串口4 串口5 备用
* 串口6 用于打印调试信息 printf() 函数
*/
#include "stm32f4xx.h"
#include "bsp_systick.h" 
#include "bsp_gpio.h"
#include "bsp_uart.h" 
#include "bsp_timer.h"
#include "bsp_usart_dma.h" 
#include "bsp_can.h" 
#include "key.h" 
#include "led.h" 

#include "DBUS/DBUS.h" 
#include "MOTOR_APSL2DB/MOTOR_APSL2DB.h" 
#include "MOTOR_RMD/MOTOR_RMD.h" 
#include "Battery/Battery.h"
#include "Mick_IO/Mick_IO.h"
#include "MOTOR_Control/MOTOR_Control.h"  

#include "lwip/tcp.h"
#include "netconf.h"
#include "tcp_echoclient.h"
#include "stm32f4x7_phy.h"
 

extern volatile Battery battery; //电池结构体数据

volatile uint32_t Timer2_Counter1=0;
volatile uint32_t Timer2_Counter2=0;
volatile uint32_t Timer2_Counter3=0; //电池任务
volatile uint32_t Timer2_Counter4=0; //IO上传任务
volatile uint32_t Timer2_Counter5=0; //电机状态监测

volatile uint8_t UART1_Flag;
volatile uint8_t UART2_DMA_Flag=0x00; //串口2中断标志位
volatile uint8_t UART2_DMA_Flag2=0x00;

volatile uint8_t UART3_Flag; //串口6中断标志位  接收电池
volatile uint8_t USART3_RX_BUF[RS485_RX_Len];  // 串口6 接收缓存
extern volatile uint8_t RS485_Recv_Data[RS485_RX_Len];//电池接收数据
 
volatile uint8_t flag_can1 = 0;		 //用于标志是否接收到数据，在中断函数中赋值
volatile uint8_t flag_can2 = 0;		  
//volatile CanTxMsg CAN2_TxMessage;		 //发送缓冲区
volatile CanRxMsg CAN1_RxMessage;		  //接收缓冲区
volatile CanRxMsg CAN2_RxMessage;		  //接收缓冲区
//extern uint8_t data_can[8];

extern volatile moto_measure_t moto_chassis[4];

volatile uint8_t motor_errors_cnt=0; //电机报错次数
volatile uint8_t motor_detect_cnt=0; //电机状态监测次数

// 以太网测试变量
extern __IO uint8_t EthLinkStatus;
__IO uint32_t LocalTime = 0;


static void TIM3_Config(uint16_t period,uint16_t prescaler);
void Main_Delay(unsigned int delayvalue);
void IWDG_Init_Config(void);
int main(void)
{
	uint8_t i=0;
	uint8_t motor_i=0;
	uint8_t flag=0;
	uint8_t speed_rpm =0;
	
	SysTick_Init(); //滴答定时器初始化
	
	Init_Mick_GPIO();// 初始化LED 隔离型输出端口

	Set_Isolated_Output(1,0);
	Set_Isolated_Output(2,0);
	Set_Isolated_Output(3,0);
	Set_Isolated_Output(4,0);
 
	//上位机通讯 串口1
	My_Config_USART_Init(USART1,115200,1);
	UART_send_string(USART1,"USART1 Chassiss for 4WS4WD .....\n");

	//printf 占用串口6
	My_Config_USART_Init(USART6,256000,1);
	UART_send_string(USART6,"USART6 Chassiss for 4WS4WD .....\n");
	
	//电池(485)初始化 占用串口3
	Battery_Init();	
	
     // DBUS 遥控器   占用串口2
	printf("RC_Remote_Init ...\n");	 
	RC_Remote_Init(); 
	printf("RC_Remote_Init Successful !\n");
	
	//---------------------CAN测试---------------------
	printf("CAN1 Init ...\n");	
	CAN_Config(CAN1);
	printf("CAN1 Init Successful !\n");	
	
	printf("CAN2 Init ...\n");	
	CAN_Config(CAN2);
	printf("CAN2 Init Successful !\n");	
	
	printf("MOTOR_APSL2DB Init ... \n");
	MOTOR_APSL2DB_Init();
	printf("MOTOR_APSL2DB Init Successful !\n");	

	printf("MOTOR_RMD Init ... \n");
	MOTOR_RMD_Init();
	printf("MOTOR_RMD Init Successful !\n");	
 
    Timer_2to7_Init(TIM6,7*1000);// 7ms
	Timer_start(TIM6);
	
    Timer_2to7_Init(TIM7,50*1000);// 50ms
	Timer_start(TIM7);
 
 	printf("Open IWDG ... \n"); //打开看门狗
	IWDG_Init_Config();
	
	printf("4ws4wd Init seccessful...\n");	
	 

	while(1)
	{
		IWDG_ReloadCounter(); //喂狗
		if(UART2_DMA_Flag) //遥控器介入控制命令逻辑  DBUS 7ms 发送一次数据
		{	
			UART2_DMA_Flag2++;
			if(UART2_DMA_Flag2>7)
			{
				LED2_FLIP;
				Set_Isolated_Output(2,1);//绿色
				//RC_Debug_Message();
				RC_Upload_Message();//上传遥控器状态
				UART2_DMA_Flag2=0;
			}			
			UART2_DMA_Flag=0x00;	
		}
		if(flag_can1)
		{
			LED3_FLIP;
			//printf("\nStdId: 0x%x   FMI: 0x%x \n",RxMessage.StdId,RxMessage.FMI); 
			//MOTOR_APSL2DB_PDO_Debug();
			
			if((moto_chassis[0].driver_status != 0x00) //表示有报警
				|| (moto_chassis[1].driver_status != 0x00) 
				|| (moto_chassis[2].driver_status != 0x00) 
				|| (moto_chassis[3].driver_status != 0x00))
			{
				motor_errors_cnt++; //每隔1秒清除一次计数	
				motor_i=0;
				for(motor_i=0;motor_i<4;motor_i++)
				{
					if((moto_chassis[0].driver_status != 0x00)) //表示有报警
					{
						 printf("Motor ID: %d  with warning !!!\n",motor_i);	
						if(((moto_chassis[motor_i].error_code_LSB & 0x80) || (moto_chassis[motor_i].error_code_HSB & 0x08)) && motor_errors_cnt<10) //驱动器输出短路 
						{
							    printf("Motor ID: %d  is overhead, now clear the error flag with reset APSL2DB\n",motor_i);	
								MOTOR_APSL2DB_Init();
						}
						else
						{
							Set_Isolated_Output(1,1);//红
						}
					}
				}				
			}
			else
			{
				Set_Isolated_Output(1,0);//红
			}
			
			Chassis_Motor_Upload_Message();
			flag_can1=0;
		}
		
		//------电机状态监测
		if(Timer2_Counter5>= 50*1) //1秒读取一次电机状态
		{
			Timer2_Counter5=0;
			
			motor_errors_cnt=0;  //电机报警次数清零
			
			motor_detect_cnt++;
			if(motor_detect_cnt<5)
				APS_L2DB_Read_Temp(motor_detect_cnt);
			else
			{
				motor_detect_cnt =0;
				if((moto_chassis[0].Temp >= 60) //表示有报警
					|| (moto_chassis[1].Temp >= 60) 
					|| (moto_chassis[2].Temp >= 60) 
					|| (moto_chassis[3].Temp >= 60))
				{
					Set_Isolated_Output(1,0);//红
				}
			}
			Chassis_MotorState_Upload_Message();
			MOTOR_RMD_Read_Cmd(1,0x9A);  //读取转向电机状态1  
			MOTOR_RMD_Read_Cmd(2,0x9A);  //读取转向电机状态1 
			MOTOR_RMD_Read_Cmd(3,0x9A);  //读取转向电机状态1 
			MOTOR_RMD_Read_Cmd(4,0x9A);  //读取转向电机状态1 
			
		}
		
		
		if(Timer2_Counter4>= 50*5) //5秒读取一次 IO状态
		{
			Isolated_IO_Upload_Message();
			Timer2_Counter4=0;
		}
		
		
		if(Timer2_Counter3>= 50*10) //10秒读取一次 电池数据
		{
			LED1_FLIP;
			//UART_send_string(USART1,"print data \n");
			Battery_Read_Reg(01, 0x0000, 0x002F);
			Timer2_Counter3=1;
		}
		if(UART3_Flag == 0x01) //解析电池数据
		{	
			//printf("Recived data: ");
			//for(i=0;i<RS485_RX_Len;i++)
			//{
			//	printf("0x%x ",RS485_Recv_Data[i]);
			//}
			//printf("\n");
			
			UART3_Flag = 0x00;
			Battery_Recived_Analy();//电池数据不需要实时解析
			if(battery.flag==0x01)
			{
				if(battery.RSOC < 10)
				{
					 Set_Isolated_Output(1,0);//红
					 Set_Isolated_Output(2,0);//绿
					 Set_Isolated_Output(3,0);//蓝		
					printf("RSOC: %d < 10 Percent\n",battery.RSOC);					
				}
				else if(battery.RSOC < 20)
				{				 
					Set_Isolated_Output(1,0);//红	
					printf("RSOC: %d < 20 Percent\n",battery.RSOC);
				}
				Battery_Debug();
				Battery_Upload_Message();
				battery.flag=0;
			}
		}

	}
  
	
//	TIM3_Config(999,899);//10ms定时器
//	printf("以太网通信例程\n");
//	
//	/* Configure ethernet (GPIOs, clocks, MAC, DMA) */
//  ETH_BSP_Config();	
//  printf("PHY初始化结束\n");
//	
//  /* Initilaize the LwIP stack */
//  LwIP_Init();	
//  
//  printf("    KEY1: 启动TCP连接\n");
//  printf("    KEY2: 断开TCP连接\n");
//  
//  /* IP地址和端口可在netconf.h文件修改，或者使用DHCP服务自动获取IP
//	(需要路由器支持)*/
//  printf("本地IP和端口: %d.%d.%d.%d\n",IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);
//  printf("远端IP和端口: %d.%d.%d.%d:%d\n",DEST_IP_ADDR0, DEST_IP_ADDR1,DEST_IP_ADDR2, DEST_IP_ADDR3,DEST_PORT);
  
	while(1)
	{
//	    /*按一次按键 CAN 发送一次数据*/
//		if(	Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON)
//		{
//			LED_BLUE;
//			CAN_SetMsg(&CAN2_TxMessage,data_can,8,0x1315,1,0);
//            printf("set complete\r\n");
//			
//			CAN_Transmit(CAN1, &CAN2_TxMessage);
//            printf("Transmit complete\r\n");
//			
//			Main_Delay(90);//等待发送完毕，可使用CAN_TransmitStatus查看状态
//	 
//			printf("\r\n ExtId: 0x%x \r\n",CAN2_TxMessage.ExtId);
//			//CAN_DEBUG_ARRAY(CAN2_TxMessage.Data,8); 
//		}
//		if(flag_can2==1)
//		{		
//			LED_GREEN;
//            //CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
//			printf("\r\nCAN recived data: \r\n");	
//			printf("\r\n ExtId: 0x%x \r\n",RxMessage.ExtId);
//			printf("\r\n FMI: 0x%x \r\n",RxMessage.FMI);
//		 
//			flag_can2=0;
//		}

		if((Key_Scan(KEY1_GPIO_PORT,KEY1_PIN)==KEY_ON) && (flag==0))
		{
			LED2_ON;
			if (EthLinkStatus == 0)
			{
				printf("connect to tcp server\n");
				/*connect to tcp server */ 
				tcp_echoclient_connect();
				flag=1;
			}
		}
		if((Key_Scan(KEY2_GPIO_PORT,KEY2_PIN)==KEY_ON) && flag)
		{
			LED2_OFF;
			tcp_echoclient_disconnect();
			flag=0;
		}
		/* check if any packet received */
		if (ETH_CheckFrameReceived())
		{ 
			/* process received ethernet packet */
			LwIP_Pkt_Handle();
		}
		/* handle periodic timers for LwIP */
		LwIP_Periodic_Handle(LocalTime);
	};
}

 //延时函数 6.3ms
void Main_Delay(unsigned int delayvalue)
{
	unsigned int i;
	while(delayvalue-->0)
	{	
		i=5000;
		while(i-->0);
	}
}
/**
  * @brief  通用定时器3中断初始化
  * @param  period : 自动重装值。
  * @param  prescaler : 时钟预分频数
  * @retval 无
  * @note   定时器溢出时间计算方法:Tout=((period+1)*(prescaler+1))/Ft us.
  *          Ft=定时器工作频率,为SystemCoreClock/2=90,单位:Mhz
  */
static void TIM3_Config(uint16_t period,uint16_t prescaler)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟
	
	TIM_TimeBaseInitStructure.TIM_Prescaler=prescaler;  //定时器分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseInitStructure.TIM_Period=period;   //自动重装载值
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
	TIM_Cmd(TIM3,ENABLE); //使能定时器3
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  定时器3中断服务函数
  * @param  无
  * @retval 无
  */
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
		LocalTime+=10;//10ms增量
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}
 
void IWDG_Init_Config(void)
{
	//取消写保护
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	
	//设置分频系统
	IWDG_SetPrescaler(IWDG_Prescaler_32); 
	//32分频  32khz/32=1khz  倒数一个数：1/1khz = 1/1000hz =0.001s = 1ms
	
	//设置重装载值
	IWDG_SetReload(2000);  //数2000个数，用时2s
	IWDG_ReloadCounter();
	
	//启动
	IWDG_Enable();
 
}